package com.bbs.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bbs.pojo.dto.MessageDto;
import com.bbs.mapper.MessageMapper;
import com.bbs.pojo.Message;
import com.bbs.pojo.dto.message.MessageContent;
import com.bbs.pojo.dto.message.UserMessageContent;
import com.bbs.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {
    @Autowired
    MessageMapper messageMapper;

    @Override
    public Long acknowledgedMessageCountByReceiver(String id) {
        QueryWrapper<Message> queryWrapper = new QueryWrapper<>();
        Message message = new Message();
        message.setReceiverId(id);
        message.setAcknowledged(false);
        queryWrapper.setEntity(message);
        return messageMapper.selectCount(queryWrapper);
    }

    @Override
    public List<MessageDto> getMessagesByReceiver(String receiverId) {
        Message message = new Message();
        message.setReceiverId(receiverId);
        QueryWrapper<Message> queryWrapper = new QueryWrapper<>(message);
        queryWrapper.ne("type", UserMessageContent.MESSAGE_TYPE);
        queryWrapper.orderByDesc("sent_time");
        List<Message> messages = messageMapper.selectList(queryWrapper);
        return messages.stream().map(MessageDto::new).collect(Collectors.toList());
    }

    @Override
    public MessageDto getMessageByIdAndReceiver(String messageId, String receiverId) {
        QueryWrapper<Message> queryWrapper = new QueryWrapper<>();
        Message message = new Message();
        message.setReceiverId(receiverId);
        message.setMessageId(messageId);
        queryWrapper.setEntity(message);
        message = messageMapper.selectOne(queryWrapper);
        if(message != null){
            return new MessageDto(message);
        }else{
            return null;
        }
    }

    @Override
    public MessageDto getMessageById(String id) {
        Message message = getById(id);
        if(message != null){
            return new MessageDto(message);
        }else{
            return null;
        }
    }

    @Override
    public boolean sendMessage(MessageDto messageDto) {
        Message message = new Message();
        message.setReceiverId(messageDto.getReceiverId());
        message.setSenderId(messageDto.getSenderId());
        message.setContent(JSON.toJSONString(messageDto.getContent()));
        message.setType(messageDto.getContent().messageType());
        return messageMapper.insert(message) == 1;
    }

    @Override
    public boolean sendMessage(Message message) {
        message.setAcknowledged(false);
        if(message.getContent() == null){
            return false;
        }
        return messageMapper.insert(message) == 1;
    }

    @Override
    public boolean acknowledgeMessage(String receiverId, List<String> messageIds) {
        List<Message> messages = new ArrayList<>();
        for (String messageId : messageIds) {
            Message message = new Message();
            message.setMessageId(messageId);
            message.setAcknowledged(true);
            messages.add(message);
        }
        return updateBatchById(messages);
    }

    @Override
    public boolean acknowledgeMessageBefore(String receiverId, LocalDateTime time) {
        UpdateWrapper<Message> updateWrapper = new UpdateWrapper<>();
        updateWrapper.le("sent_time", time);
        updateWrapper.eq("receiver_id", receiverId);
        //排除用户间消息
        updateWrapper.ne("type", UserMessageContent.MESSAGE_TYPE);
        updateWrapper.set("acknowledged", true);
        return update(updateWrapper);
    }

    @Override
    public boolean deleteMessage(MessageDto messageDto) {
        Message message = new Message();
        message.setReceiverId(messageDto.getReceiverId());
        message.setSenderId(messageDto.getSenderId());
        message.setMessageId(messageDto.getMessageId());
        message.setType(messageDto.getType());
        message.setAcknowledged(messageDto.getAcknowledged());
        message.setSentTime(messageDto.getSendTime());
        if(messageDto.getContent() != null){
            message.setContent(JSON.toJSONString(messageDto.getContent()));
        }
        return remove(new QueryWrapper<>(message));
    }
}
